package com.jumi.microservice.yzhpay.pay.notify;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jumi.microservice.common.utils.DateUtil;
import com.jumi.microservice.constant.usercash.CpsCashStatusEnum;
import com.jumi.microservice.dto.userWallet.WalletInOrOutRequest;
import com.jumi.microservice.entity.CpsUserCash;
import com.jumi.microservice.enumerate.CpsWalletTypeEnum;
import com.jumi.microservice.mapper.CpsUserCashMapper;
import com.jumi.microservice.service.usercash.admin.AdminCpsWalletInOrOutService;
import com.jumi.microservice.yzhpay.constant.ConfigPath;
import com.jumi.microservice.yzhpay.constant.YzhPayStatusEnum;
import com.jumi.microservice.yzhpay.notify.BackNotifyMessage;
import com.jumi.microservice.yzhpay.util.DESUtil;
import com.jumi.microservice.yzhpay.util.JsonUtil;
import com.jumi.microservice.yzhpay.util.Property;
import com.jumi.microservice.yzhpay.util.RSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.net.URLDecoder;

/**
 * 接收云账户后台回调接口
 * 支付流程为同步接单，异步支付。
 * 下单接口返回成功代表云账户已经收到该订单，支付结果依赖于异步通知。
 **/
@RestController
public class ReceiveNotify {
    private static final Logger log = LoggerFactory.getLogger(ReceiveNotify.class);
    @Resource
    private CpsUserCashMapper userCashMapper;
    @Resource
    AdminCpsWalletInOrOutService adminCpsWalletInOrOutService;

    @PostMapping("/yzh/cps/notify")
    public Object receiveNotifyMessage(@RequestBody String message) throws Exception {
        NotifyResponse notifyResponse = JsonUtil.fromData(message, NotifyResponse.class);
        // 3DES解密
        BackNotifyMessage backNotifyMessage = JsonUtil.fromJson(DESUtil.decode(notifyResponse.getData()), BackNotifyMessage.class);
        log.info("云账户返回参数: [{}]", JSON.toJSONString(backNotifyMessage.getData()));
        String payNo = backNotifyMessage.getData().getOrder_id();
        QueryWrapper<CpsUserCash> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", CpsCashStatusEnum.STATUS_AUDIT_PASSED.getCode());
        queryWrapper.eq("pay_no", payNo);
        CpsUserCash userCash = userCashMapper.selectOne(queryWrapper);
        // 回调数据验签
        if (!RSAUtil.verify(URLDecoder.decode(notifyResponse.getPlain(), "UTF-8"), URLDecoder.decode(notifyResponse.getSign(), "UTF-8"), Property.getProperties(ConfigPath.YZH_RSA_PUBLIC_KEY))) {
            if (userCash != null) {
                // TODO: 回滚提现金额到钱包
                int payStatus = CpsCashStatusEnum.STATUS_CASH_FAILED.getCode();
                //返还金额到钱包
                WalletInOrOutRequest walletInOrOutRequest = new WalletInOrOutRequest();
                walletInOrOutRequest.setAmount(userCash.getCashAmount());
                walletInOrOutRequest.setRemark(CpsWalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
                walletInOrOutRequest.setUserId(userCash.getUid());
                walletInOrOutRequest.setType(CpsWalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
                walletInOrOutRequest.setOrderNo(userCash.getOrderNo());
                walletInOrOutRequest.setOrderId(userCash.getId());
                adminCpsWalletInOrOutService.walletIn(walletInOrOutRequest);
                // 更新支付状态
                userCash.setStatus((byte) payStatus);
                userCash.setPayTime(DateUtil.parse(backNotifyMessage.getData().getFinished_time(), "yyyy-MM-dd HH:mm:ss"));
                userCash.setPayStatus(backNotifyMessage.getData().getStatus());
                userCash.setPayStatusMessage(backNotifyMessage.getData().getStatus_message());
                userCash.setPayStatusDetail(backNotifyMessage.getData().getStatus_detail());
                if (!"".equals(backNotifyMessage.getData().getStatus_detail_message())) {
                    userCash.setPayStatusDetailMessage(backNotifyMessage.getData().getStatus_detail_message());
                }
                userCashMapper.updateById(userCash);
            }
            log.info("RSA验签失败，请确认公钥是否正确！");
            return "failure";
        }
        /*
         * 订单状态码:
         * -1 删除（最终状态，不会回调）
         * 0-已受理（中间状态，不会回调）
         * 1-已打款（最终状态，会回调）
         * 2-打款失败（最终状态，会回调）
         * 4-待打款(暂停处理)（中间状态，会回调）
         * 5-打款中(状态未知)（中间状态，不会回调）
         * 8-待打款（中间状态，不会回调）
         * 9-打款失败（已退款，退汇或者冲正)（最终状态，会回调）
         * 15-取消支付（最终状态，会回调）
         * 银⾏卡和⽀付宝通道打款，仅需要订单状态码status即可判断订单是否打款成功：1成功，2或9失败，15取消⽀付。
         * 对于状态1（已打款），在⽆退汇情况下是最终状态（退汇存在于银⾏卡通道：⽤户银⾏卡为II/III类银⾏卡收款超限额，导致打款先成功后退汇（较少情况））
         */
        if (userCash != null) {
            // TODO: 回滚提现金额到钱包
            int payStatus = CpsCashStatusEnum.STATUS_AUDIT_PASSED.getCode();
            if (backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_SUCCESS.getCode())) {
                // status: 1-已打款
                // TODO: 更新打款状态
                payStatus = CpsCashStatusEnum.STATUS_CASH_ACCOUNT.getCode();
                log.info("云账户平台，已打款！");
            } else if (backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_FAIL.getCode())
                    || backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_FAIL_OTHER.getCode())
                    || backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_CANCEL.getCode())
            ) {
                if (backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_CANCEL.getCode())) {
                    log.info("云账户平台，取消打款！");
                } else {
                    log.info("云账户平台，打款失败！");
                }
                // status: 2-打款失败 9-打款失败（已退款，退汇或者冲正) 15-取消支付
                // TODO: 回滚提现金额到钱包
                payStatus = CpsCashStatusEnum.STATUS_CASH_FAILED.getCode();
                //返还金额到钱包
                WalletInOrOutRequest walletInOrOutRequest = new WalletInOrOutRequest();
                walletInOrOutRequest.setAmount(userCash.getCashAmount());
                walletInOrOutRequest.setRemark(CpsWalletTypeEnum.FAIL_WITHDRAW_IN.getMsg());
                walletInOrOutRequest.setUserId(userCash.getUid());
                walletInOrOutRequest.setType(CpsWalletTypeEnum.FAIL_WITHDRAW_IN.getCode());
                walletInOrOutRequest.setOrderNo(userCash.getOrderNo());
                walletInOrOutRequest.setOrderId(userCash.getId());
                adminCpsWalletInOrOutService.walletIn(walletInOrOutRequest);
            }else if (backNotifyMessage.getData().getStatus().equals(YzhPayStatusEnum.YZH_PAY_STATUS_WAIT_PAUSE.getCode())) {
                // status: 4-待打款(暂停处理)
                log.info("云账户平台，待打款(暂停处理)！");
            }
            // 更新支付状态
            userCash.setStatus((byte) payStatus);
            userCash.setPayTime(DateUtil.parse(backNotifyMessage.getData().getFinished_time(), "yyyy-MM-dd HH:mm:ss"));
            userCash.setPayStatus(backNotifyMessage.getData().getStatus());
            userCash.setPayStatusMessage(backNotifyMessage.getData().getStatus_message());
            userCash.setPayStatusDetail(backNotifyMessage.getData().getStatus_detail());
            if (!"".equals(backNotifyMessage.getData().getStatus_detail_message())) {
                userCash.setPayStatusDetailMessage(backNotifyMessage.getData().getStatus_detail_message());
            }
            userCashMapper.updateById(userCash);
        }
        return "success";
    }
}
